//
//  ViewController.m
//  NetRequesProject
//
//  Created by 蓓蕾 on 2021/9/6.
//

#import "ViewController.h"

@interface ViewController ()<UITableViewDelegate, UITableViewDataSource>
@property (nonatomic, strong) NSArray *dataArr;
@property (nonatomic, strong) UITableView *tableView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor whiteColor];
    
    _dataArr = @[
        @"先执行  任务一，任务二(异步执行)，再执行任务三，最后在主线程刷新数据",
        @"先执行  任务一、任务二、任务三(异步执行)，最后在主线程刷新数据",
        @"两个同步方法之间有依赖关系"
        ,@"图片合成"];
    
    [self initTableView];
    NSLog(@"成功启动");
}

-(void)initTableView
{
    _tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];
    [self.view addSubview:_tableView];
    [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"UITableViewCell"];
    _tableView.delegate = self;
    _tableView.dataSource = self;
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _dataArr.count;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 80;
}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    if (indexPath.row < _dataArr.count) {
        NSString *titleString = _dataArr[indexPath.row];
        cell.textLabel.text = titleString;
        cell.textLabel.font = [UIFont systemFontOfSize:15];
        cell.textLabel.numberOfLines = 0;
    }
    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    if (indexPath.row == 0) {//先执行  任务一，任务二(异步执行)，再执行任务三，最后在主线程刷新数据
        [self requestNetDataOne];
    }
    else if (indexPath.row == 1)
    {//先执行  任务一、任务二、任务三(异步执行)，最后在主线程刷新数据
        [self requestNetDataTwo];
    }
    else if (indexPath.row == 2)
    {//两个同步方法之间有依赖关系
        [self createOperationQueue];
    }
    else if (indexPath.row == 3)
    {//图片合成
        [self createPictureSynthesis];
    }
}

#pragma mark - 先执行  任务一，任务二(异步执行)，再执行任务三，最后在主线程刷新数据
-(void)requestNetDataOne
{
    MJWeakSelf
    //创建一个并行队列
    [DDProgressHUD show];
    dispatch_queue_t queque = dispatch_queue_create("GoyakodCreated", DISPATCH_QUEUE_CONCURRENT);
    //异步执行
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    dispatch_async(queque, ^{
        [weakSelf requestOneMethod:semaphore];
        [weakSelf requestTwoMethod:semaphore];
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        [weakSelf requestThreeMethod:semaphore];
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"所有请求任务已完成，进入主线程");
            
            [DDProgressHUD dismiss];
        });
    });
}
#pragma mark - 先执行  任务一、任务二、任务三(异步执行)，最后在主线程刷新数据
-(void)requestNetDataTwo
{
    MJWeakSelf
    [DDProgressHUD show];
    //创建信号量
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    //创建全局并行队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_group_t group = dispatch_group_create();
    dispatch_group_async(group, queue, ^{
        [weakSelf requestOneMethod:semaphore];
    });
    dispatch_group_async(group, queue, ^{
        [weakSelf requestTwoMethod:semaphore];
    });
    dispatch_group_async(group, queue, ^{
        [weakSelf requestThreeMethod:semaphore];
    });
    dispatch_group_notify(group, queue, ^{
        //几个请求对应几次信号等待
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"处理完网络请求后，最后处理事件");
        NSLog(@"currentThread = %@",[NSThread currentThread]);
        dispatch_sync(dispatch_get_main_queue(), ^{
            
            [DDProgressHUD dismiss];
        });
        
    });
}
#pragma mark - 两个同步方法之间有依赖关系
-(void)createOperationQueue
{
    [DDProgressHUD show];
//A依赖于B，即B先执行完，再执行A（A、B为同步执行）（无法应用于网络请求，网络请求是异步执行的）
    NSOperationQueue * queueeTest = [[NSOperationQueue alloc]init];
    queueeTest.maxConcurrentOperationCount = 1;
    NSBlockOperation * optionA = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"开始执行操作A");
        NSLog(@"A：currentThread = %@",[NSThread currentThread]);
        for (NSInteger i = 0; i < 1000; i++) {
            
        }
        NSLog(@"操作A执行完毕");
    }];
    NSBlockOperation * optionB = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"开始执行操作B");
        NSLog(@"B：currentThread = %@",[NSThread currentThread]);
        for (NSInteger i = 0; i < 1000; i++) {
            
        }
        NSLog(@"操作B执行完毕");
    }];
    
    NSBlockOperation *finishedOperation = [NSBlockOperation blockOperationWithBlock:^{
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            NSLog(@"全部执行完毕，回到主线程");
            [DDProgressHUD dismiss];
        }];
    }];

    //A依赖于B
    [optionA  addDependency:optionB];
    [finishedOperation addDependency:optionA];
    [finishedOperation addDependency:optionB];
    
    
    [queueeTest addOperation:optionA];
    [queueeTest addOperation:optionB];
    [queueeTest addOperation:finishedOperation];
}
#pragma mark - 图片合成
-(void)createPictureSynthesis
{
    NSOperationQueue  *queueOp = [[NSOperationQueue alloc]init];
    __block UIImage  *image1 = nil;
    
    //下载图片1
    NSBlockOperation  *downLoad1 = [NSBlockOperation blockOperationWithBlock:^{
        NSURL  *url = [NSURL URLWithString:@"https://upload-images.jianshu.io/upload_images/6687791-5ad29d1a5c1c84db.jpeg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"];
        
        image1 = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
        
    }];
    
    __block  UIImage  *image2 = nil;
    NSBlockOperation  *downLoad2 = [NSBlockOperation blockOperationWithBlock:^{
        
        NSURL  *url = [NSURL URLWithString:@"https://upload-images.jianshu.io/upload_images/6687791-2a51b4b27040ed41.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240"];
        
        image2 = [UIImage imageWithData:[NSData dataWithContentsOfURL:url]];
    }];
    
    
    
    //4.等待两张图片下载完成，将两张图片合成一张
    
    NSBlockOperation  *combine = [NSBlockOperation blockOperationWithBlock:^{
        //开启新的图形上下文
        UIGraphicsBeginImageContext(CGSizeMake(300, 300));
        //绘制图片
        [image1 drawInRect:CGRectMake(0, 0, 300, 150)];
        image1 = nil;
        [image2 drawInRect:CGRectMake(0, 150, 300, 150)];
        image2 = nil;
        //取得图形上下文中的图片
        UIImage  *newImage = UIGraphicsGetImageFromCurrentImageContext();
        //结束上下文
        UIGraphicsEndImageContext();
        //回到主线程显示图片
        
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            NSLog(@"照片合成完成");
            
            UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake([[UIScreen mainScreen] bounds].size.width / 2 - 150, [[UIScreen mainScreen] bounds].size.height / 2 - 150, 300, 300)];
            [self.view addSubview:imageView];
            imageView.image = newImage;
            //显示5秒后，自动消失
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [imageView removeFromSuperview];
            });
        }];
        
        
    }];
    //combine合成任务的执行依赖 downLoad1  和 downLoad2的执行完成
    [combine addDependency:downLoad1];
    [combine addDependency:downLoad2];
    
    //三个任务添加到操作队列中
    [queueOp addOperation:downLoad1];
    [queueOp addOperation:downLoad2];
    [queueOp addOperation:combine];
}

-(void)requestOneMethod:(dispatch_semaphore_t)semaphore
{
    NSMutableDictionary *parama = [NSMutableDictionary new];
    parama[@"longitude1"] = [NSString stringWithFormat:@"113.596680"];
    parama[@"latitude1"] = [NSString stringWithFormat:@"34.746661"];
    [NetRequest POSTWithBodyRow:@"http://www.zzbeilei.net/app/pre/index" parameters:parama showLog:NO logTitle:@"获取预约首页数据" success:^(id  _Nullable responseObject) {
        NSLog(@"请求一");
        
        dispatch_semaphore_signal(semaphore);
    } failure:^(NSError * _Nonnull error) {
        
        dispatch_semaphore_signal(semaphore);
    }];
}

-(void)requestTwoMethod:(dispatch_semaphore_t)semaphore
{
    NSMutableDictionary *parama = [NSMutableDictionary new];
    parama[@"longitude1"] = [NSString stringWithFormat:@"113.596680"];
    parama[@"latitude1"] = [NSString stringWithFormat:@"34.746661"];
    [NetRequest POSTWithBodyRow:@"http://www.zzbeilei.net/app/pre/index" parameters:parama showLog:NO logTitle:@"获取预约首页数据" success:^(id  _Nullable responseObject) {
        NSLog(@"请求二");
        
        dispatch_semaphore_signal(semaphore);
    } failure:^(NSError * _Nonnull error) {
        
        dispatch_semaphore_signal(semaphore);
    }];
}

-(void)requestThreeMethod:(dispatch_semaphore_t)semaphore
{
    NSMutableDictionary *parama = [NSMutableDictionary new];
    parama[@"longitude1"] = [NSString stringWithFormat:@"113.596680"];
    parama[@"latitude1"] = [NSString stringWithFormat:@"34.746661"];
    [NetRequest POSTWithBodyRow:@"http://www.zzbeilei.net/app/pre/index" parameters:parama showLog:NO logTitle:@"获取预约首页数据" success:^(id  _Nullable responseObject) {
        NSLog(@"请求三");
        
        dispatch_semaphore_signal(semaphore);
    } failure:^(NSError * _Nonnull error) {
        
        dispatch_semaphore_signal(semaphore);
    }];
}


@end
